package com.runfast.common.web.interceptor;

import com.runfast.common.Constants;
import com.runfast.common.utils.JsonUtils;
import com.runfast.common.web.entity.Result;
import com.runfast.common.web.entity.ResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @author: lijin
 * @date: 2018年02月28日
 */
public class MaliciousRequestInterceptor extends HandlerInterceptorAdapter {
    private static final Logger LOGGER = LoggerFactory.getLogger(MaliciousRequestInterceptor.class);
    private Boolean allRequest = false; // 拦截所有请求,否则拦截相同请求
    private Long minRequestIntervalTime = 100l; // 允许的最小请求间隔
    private Integer maxMaliciousTimes = 5; // 允许的最大恶意请求次数

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST,GET,PUT,OPTIONS,DELETE");
        response.setHeader("Access-Control-Allow-Headers",
                "x-requested-with,Access-Control-Allow-Origin,EX-SysAuthToken,EX-JSESSIONID");

        String url = request.getServletPath();
        HttpSession session = request.getSession();
        String preRequest = (String) session.getAttribute(Constants.PREREQUEST_URL);
        Long preRequestTime = (Long) session.getAttribute(Constants.PREREQUEST_TIME);
        if (preRequestTime != null && preRequest != null) { // 过滤频繁操作
            if ((url.equals(preRequest) || allRequest)
                    && System.currentTimeMillis() - preRequestTime < minRequestIntervalTime) {
                Integer maliciousRequestTimes = (Integer) session.getAttribute(Constants.MALICIOUS_REQUEST_TIMES);
                if (maliciousRequestTimes == null) {
                    maliciousRequestTimes = 1;
                } else {
                    maliciousRequestTimes++;
                }
                session.setAttribute(Constants.MALICIOUS_REQUEST_TIMES, maliciousRequestTimes);
                LOGGER.info("======" + maliciousRequestTimes + "======" + this);
                /*if (maliciousRequestTimes > maxMaliciousTimes) {


                    Result fail = Result.fail(ResultCode.FREQUENT_OPRATION);
                    response.setStatus(HttpStatus.OK.value());
                    response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
                    response.getWriter().println(JsonUtils.getMapper().writeValueAsString(fail));
                    return false;
                } else {
                    response.setStatus(HttpStatus.MULTI_STATUS.value());
                    return false;
                }*/

                response.setStatus(HttpStatus.MULTI_STATUS.value());
                return false;
            } else {
                session.setAttribute(Constants.MALICIOUS_REQUEST_TIMES, 0);
            }
        }
        session.setAttribute(Constants.PREREQUEST_URL, url);
        session.setAttribute(Constants.PREREQUEST_TIME, System.currentTimeMillis());
        return super.preHandle(request, response, handler);
    }

    public void setAllRequest(Boolean allRequest) {
        this.allRequest = allRequest;
    }

    public void setMinRequestIntervalTime(Long minRequestIntervalTime) {
        this.minRequestIntervalTime = minRequestIntervalTime;
    }

    public void setMaxMaliciousTimes(Integer maxMaliciousTimes) {
        this.maxMaliciousTimes = maxMaliciousTimes;
    }
}
